#include "STC8G.h"
#include "intrins.h"

#define FOSC 22118400UL
#define BRT (65536 - FOSC / 9600 / 4)

volatile unsigned int TimingDelay;

bit busy;

unsigned char BatBuffer[16];
char BatPoint = 2;
char BatCmd[6] = {0x06, 0x01, 0x10, 0x00, 0x00, 0x17};
char BatRxState = 0;      //0:初始化
                          //1:收到包头0x01
                          //2:收到包头0x01 0x10
unsigned int BatVolt = 0; //电池组电压
unsigned char BatTemp = 0;
unsigned char BatState = 0;
bit BatRx = 0;
unsigned int BatTimer; //电池轮询计时器

unsigned char HostBuffer[40];
char HostPoint = 2;
char HostRxState = 0; //0:初始化
                      //1:收到包头0xFE
                      //2:收到包头0xFE 0xFE
                      //3:收到包头0xFE 0xFE 0x55
                      //4:收到包头0xFE 0xFE 0x55 0xAA
unsigned char HostResp[24] = {0xFF, 0xFF, 0x55, 0xAA, 0x00, 0x03, 0x00, 0x10, 0xFF, 0xA1, 0xA0, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16};
bit HostRx = 0;

unsigned int EnableDelay = 0;

char DataCheckSum(char *Buf, char num) reentrant
{
    char i;
    char CheckSum = 0;
    for (i = 0; i < num; i++)
    {
        CheckSum = CheckSum + Buf[i];
    }
    return CheckSum;
}

void UartIsr() interrupt 4
{
    if (TI)
    {
        TI = 0;
        busy = 0;
    }
    if (RI)
    {
        RI = 0;
        switch (HostRxState)
        {
        case 0:
            if (SBUF == 0xFE)
            {
                HostRxState = 1;
            }
            break;
        case 1:
            if (SBUF == 0xFE)
            {
                HostRxState = 2;
            }
            else
                HostRxState = 0;
            break;
        case 2:
            if (SBUF == 0x55)
            {
                HostBuffer[0] = SBUF;
                HostRxState = 3;
            }
            else
                HostRxState = 0;
            break;
        case 3:
            if (SBUF == 0xAA)
            {
                HostBuffer[1] = SBUF;
                HostPoint = 2;
                HostRxState = 4;
            }
            else
                HostRxState = 0;
            break;
        case 4:
            if (HostPoint < 12 || HostPoint < (HostBuffer[5] + 5))
            {
                HostBuffer[HostPoint] = SBUF;
                HostPoint++;
            }
            else if (HostPoint == (HostBuffer[5] + 5) && SBUF == 0x16 && HostBuffer[HostPoint - 1] == DataCheckSum(HostBuffer, HostPoint - 1))
            //else if (HostPoint ==12)
            {
                HostRxState = 0;
                HostRx = 1;
            }
            else
            {
                HostRxState = 0;
            }
            break;

        default:
            break;
        }
    }
}

void Uart2Isr() interrupt 8
{
    if (S2CON & 0x02)
    {
        S2CON &= ~0x02;
        busy = 0;
    }
    if (S2CON & 0x01)
    {
        S2CON &= ~0x01;
        switch (BatRxState)
        {
        case 0:
            if (S2BUF == 0x01)
            {
                BatBuffer[0] = S2BUF;
                BatRxState = 1;
            }
            break;
        case 1:
            if (S2BUF == 0x10)
            {
                BatBuffer[1] = S2BUF;
                BatPoint = 2;
                BatRxState = 2;
            }
            else
                BatRxState = 0;
            break;
        case 2:
            if (BatPoint < 14)
            {
                BatBuffer[BatPoint] = S2BUF;
                BatPoint++;
            }
            else
            {
                if (S2BUF == DataCheckSum(BatBuffer, 14))
                {
                    BatVolt = BatBuffer[2];
                    BatVolt = BatVolt << 8;
                    BatVolt = BatVolt + BatBuffer[3];
                    BatTemp = BatBuffer[12];
                    BatState = BatBuffer[10];
                    // BatRx = 1;
                }
                BatRxState = 0;
            }
            break;

        default:
            break;
        }
    }
}

void UartInit()
{
    //配置定时器2
    T2L = BRT;
    T2H = BRT >> 8;
    //配置UART1
    SCON = 0x50; //8位数据，允许接收
    AUXR = 0x15; //定时器2启动 1T模式 定时器2作为UART1波特率发生器
    //配置UART2
    S2CON = 0x10;
    //使能中断
    ES = 1;
    IE2 |= 0x01;
    busy = 0;
}

void UartSend(char dat)
{
    P15 = 1;
    IE2 &= 0xFE;
    busy = 1;
    SBUF = dat;
    while (busy)
        ;
    IE2 |= 0x01;
    P15 = 0;
}
void UartSendResp(char *Resp)
{
    char count;
    for (count = 0; count < 24; count++)
    {
        UartSend(Resp[count]);
    }
}

void Uart2Send(char dat)
{
    P37 = 1;
    ES = 0;
    busy = 1;
    S2BUF = dat;
    while (busy)
        ;
    ES = 1;
    P37 = 0;
}
void Uart2SendCmd(char *Cmd, char num)
{
    char i;
    for (i = 0; i < num; i++)
    {
        Uart2Send(Cmd[i]);
    }
    BatRxState = 0;
}

void TIM0Init()
{
    TMOD = 0x00; //模式0
    TL0 = 0x00;  //65536-12.000M/12/1000
    TH0 = 0xB8;
    TR0 = 1; //启动定时器
    ET0 = 1; //使能定时器中断
}

void TIM0_Isr() interrupt 1
{
    BatTimer++;
    if (TimingDelay != 0x00)
    {
        TimingDelay--;
    }
}

// void Delay(unsigned int nTime)
// {
//     TimingDelay = nTime;

//     while (TimingDelay != 0)
//         ;
// }

void main()
{
    P1M1 = 0x00;
    P1M0 = 0xA2;
    P3M1 = 0x00;
    P3M0 = 0x8C;
    P_SW1 = 0x80; //RXD_3/P1.6, TXD_3/P1.7
    P15 = 0;
    UartInit();
    TIM0Init();
    EA = 1;
    while (1)
    {
        if (P13 == 0) //打开允许
        {
            if (EnableDelay <= 10000)
            {
                EnableDelay++;
            }
            else
            {
                if (P34)
                {
                    P33 = 0;
                    P32 = 1; //打开
                }
                else
                {
                    P32 = 0;
                    P33 = 0;
                }
            }
        }
        else
        {
            EnableDelay = 0;
            if (P35)
            {
                P32 = 0;
                P33 = 1; //关闭
            }
            else
            {
                P32 = 0;
                P33 = 0;
            }
        }
        if (HostRx == 1)
        {
            HostResp[12] = HostBuffer[10] + 1; //报文ID+1
            if ((BatState & 0x08) == 0x08)     //充电状态
            {
                HostResp[13] = 1;
            }
            else if (BatState & 0x04 == 0x04) //放电状态
            {
                HostResp[13] = 2;
            }
            else
            {
                HostResp[13] = 0;
            }
            HostResp[14] = BatVolt & 0xff;                  //电压低位
            HostResp[15] = BatVolt >> 8;                    //电压高位
            HostResp[18] = BatTemp;                         //温度
            HostResp[22] = DataCheckSum(&HostResp + 2, 20); //校验和计算
            UartSendResp(HostResp);                         //报文发送
            HostRx = 0;
        }
        if (BatTimer >= 100)
        {
            Uart2SendCmd(BatCmd, 6);
            BatTimer = 0;
        }
    }
}

//FE FE 55 AA 00 03 00 07 FF 91 A0 11 56 A0 16 主机测试
